<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>Fastjs Builder</title>
    <script src="./ajax.fs.js" type="text/javascript"></script>
</head>
<!--suppress CssUnusedSymbol -->
<style>
    body {
        background: #2d2d2d;
        padding: 20px;
    }

    h3 {
        margin: 0;
        color: white;
    }

    button {
        background: white;
        border: none;
        width: 130px;
        height: 30px;
        cursor: pointer;
        transition: 0.6s;
        margin-top: 50px;
    }

    button:hover {
        background: #9a9a9a;
    }

    button[status=none] {
        cursor: not-allowed;
        color: #c9c9c9;
        background: #ff7474;
    }

    button[status=none]:hover {
        cursor: not-allowed;
        color: #ffffff;
        background: #ff2d2d;
    }

    .fastjs-upload {
        width: 400px;
        padding: 20px;
        border: 1px solid #a0a0a0;
        margin-top: 40px;
    }

    .fastjs-upload span {
        color: white;
        font-size: 13px;
    }

    .fastjs-upload button {
        height: 24px;
        margin: 0;
    }

    .plugin-upload {
        width: 400px;
        padding: 20px;
        border: 1px solid #a0a0a0;
        margin-top: 40px;
    }

    .plugin-upload span {
        color: white;
        font-size: 13px;
    }

    .plugin-upload button {
        height: 24px;
        margin: 0;
    }

    .plugin-upload #pg_list {
        color: white;
        border: 1px solid white;
        padding: 8px 8px 8px 10px;
        font-size: 12px;
        margin-top: 5px;
        margin-bottom: 5px;
    }

    #list-inside .name {
        display: inline-block;
        width: 250px;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        padding-right: 10px;
    }

    #list-inside .size {
        display: inline-block;
        overflow: hidden;
        width: 65px;
    }

    #list-inside .error {
        display: inline-block;
        color: red;
        cursor: pointer;
        user-select: none;
        margin-left: 10px;
        overflow: hidden
    }

    input[type=radio] {
        margin: 0 6px 0 0;
    }
</style>
<body>
<h3>Fastjs Builder</h3>
<div class="fastjs-upload">
    <span>Upload Fastjs:&nbsp;</span>
    <button id="fs_up" onclick="document.getElementById(`fastjs`).click()">Select a file...</button><br/>
    <input id="normal_mode" type="radio" name="mode" onclick="per_fs($(`#fastjs`))"  checked /><span>Normal Mode</span>
    <div id="safety_box"></div>
    <input type="file" id="fastjs" onchange="per_fs(this)" hidden/>
    <span>Fastjs version:&nbsp;<span id="fs_ver">waiting...</span></span><br/>
    <span>File size:&nbsp;<span id="fs_sz">0.00 kb</span></span><br/>
    <span>After build size:&nbsp;<span id="fs_bd_sz">0.00 kb</span></span><br/>
    <span>Status:&nbsp;<span id="fs_st">waiting upload</span></span>
</div>
<div class="plugin-upload">
    <span>Upload Plugin:&nbsp;</span>
    <button id="pg_up" onclick="document.getElementById(`plugin`).click()">Select a file</button>
    <input type="file" id="plugin" onchange="per_pg(this)" hidden/><br/>
    <div id="pg_list">
        <span id="non-upload">No plugin upload</span>
        <div id="list-inside"></div>
    </div>
    <span>Plugins number:&nbsp;<span id="pg-qt">0</span></span><br/>
    <span>Plugins size:&nbsp;<span id="pg-sz">0.00 kb</span></span>
</div>
<button id="build" status="none" onclick="build()">Build Fastjs</button>
</body>
<script about="build">
    window.safeMode = null;
    window.version = void 0;

    function build() {
        if ($("#build").getAttribute("status") === "none") {
            return void 0;
        }
        let js = window.fastjs_index
        plugin.list.forEach((e) => {
            js += "\r\n"
            js += e.index
        })
        let sub = new ajax("https://fastjs.com.cn/soft.php")
        sub.config.data = {data: js}
        sub.config.callback = result => {
            exportRaw(`fastjs-${window.version}.minjs.js`, result.data)
        }
        sub.post()
    }
    function $(e) {
        return document.querySelector(e);
    }

    function fakeClick(obj) {
        var ev = document.createEvent("MouseEvents");
        ev.initMouseEvent("click", true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
        obj.dispatchEvent(ev);
    }

    function exportRaw(name, data) {
        var urlObject = window.URL || window.webkitURL || window;
        var export_blob = new Blob([data]);
        var save_link = document.createElementNS("http://www.w3.org/1999/xhtml", "a")
        save_link.href = urlObject.createObjectURL(export_blob);
        save_link.download = name;
        fakeClick(save_link);
    }
    window.error = {
        main: true,
        plugin: false
    }

    function checkError() {
        window.error.plugin = false
        plugin.list.forEach((e)=>{
            if (e.error) {
                window.error.plugin = true
            }
        })
        let er = window.error.plugin || window.error.main
        if (er)
            $("#build").setAttribute("status", "none")
        else {
            $("#build").setAttribute("status", "ready")
        }
        return er
    }

    var plugin = {
        size: 0
    }
    plugin.list = new Proxy([], {
        set(target, name, value, receiver) {
            target[name] = value
            plugin.size = 0;
            target.forEach((e) => {
                plugin.size += e.index.length
            })
            $("#pg-qt").innerText = target.length;
            $("#pg-sz").innerText = kb(plugin.size);
            if (target.length === 0) {
                $("#list-inside").innerHTML = ""
                $("#non-upload").hidden = false
            } else {
                $("#non-upload").hidden = true
                let el = ""
                target.forEach((e, key) => {
                    el += `<div><span class="name" ${e.error === true ? "style='color:red'" : ""}>${e.name}</span><span class="size">${kb(e.index.length)}</span><span class="error" onclick="plugin.list.splice(${key}, 1);checkError()">Delete</span></div>`
                })
                $("#list-inside").innerHTML = el
                checkError()
            }
            return true;
        }
    })

    function per_pg(e) {
        var input = e;
        var reader = new FileReader();
        reader.readAsText(input.files[0]);
        reader.onload = function () {
            if (reader.result) {
                let text = reader.result;
                let search = false;
                plugin.list.forEach((e) => {
                    if (search) {
                        return void 0;
                    }
                    if (e.index === text) {
                        search = true
                    }
                })
                if (!search) {
                    let path = e.value
                    path = path.match(/[^\\]+$/g)[0]
                    plugin.list.push({
                        name: path,
                        index: text,
                        error: path.match(/^[A-z0-9.]+(.fs.js)$/g) === null
                    })
                }
            }
        }
    }

    function per_fs(e) {
        var input = e;
        var reader = new FileReader();
        reader.readAsText(input.files[0]);
        reader.onload = function () {
            if (reader.result) {
                let text = reader.result;
                let version = text.match(/(Fastjs Token \? -- < v)[.0-9]+( > -- \? Fastjs Token)/g);
                let box = $("#safety_box")
                if (version !== null) {
                    if (!$("#normal_mode").checked) {
                        text = text.replaceAll(new RegExp(`(\\/\\* --- ${window.safeMode} safety mode start --- \\*\\/)[^/*]+(\\/\\* --- ${window.safeMode} safety mode end --- \\*\\/)`, "g"), "")
                    }
                    version = version[0].match(/(v)[.0-9]+/g)[0];
                    window.version = version.substr(1);
                    $("#fs_ver").innerHTML = version;
                    $("#fs_up").style.background = "#a1ff9e";
                    $("#fs_sz").innerHTML = kb(text.length);
                    $("#fs_up").innerHTML = "Change a file";
                    $("#fs_st").innerHTML = `Upload success (version ${version})`
                    window.error.main = false
                    let list = eval(text.match(/(Safety List: \[)[,\-A-z0-9"]+(])/g)[0].match(/(\[)[,\-A-z0-9"]+(])/)[0])
                    if (box.getAttribute("list") != '["' + list?.join("\",\"") + '"]') {
                        box.setAttribute("list", '["' + list?.join("\",\"") + '"]')
                        box.innerHTML = null
                        list.forEach((item)=>{
                            box.innerHTML = `${box.innerHTML}<div class="line"><input type="radio" name="mode" onclick="per_fs($(\`#fastjs\`));window.safeMode='${item}'" /><span>${item} Safety Mode</span></div>`
                        })
                    }
                } else {
                    $("#fs_ver").innerHTML = "unknown";
                    $("#fs_up").style.background = "#ff8a8a";
                    $("#fs_up").innerHTML = "Upload again";
                    $("#fs_sz").innerHTML = kb(text.length);
                    $("#fs_st").innerHTML = `Unrecognized file,Upload again.`;
                    window.error.main = true
                    box.innerHTML = ""
                }
                checkError()
                let send = new ajax("https://fastjs.com.cn/soft.php");
                send.config.data = {data: text}
                send.config.callback = result => {
                    if (result.data.indexOf("errors\":[{\"status\":") !== -1) {
                        $("#fs_bd_sz").innerHTML = "error"
                        window.error.main = true
                    } else {
                        window.fastjs_index = result.data
                        $("#fs_bd_sz").innerHTML = kb(result.data.length)
                    }
                    checkError()
                }
                send.config.failed = () => {
                    $("#fs_bd_sz").innerHTML = "error"
                }
                send.post()
                $("#fs_bd_sz").innerHTML = "have a wait..."
            }
        };
    }

    function kb(length) {
        let kb = String(length / 1024);
        kb = kb.match(/[0-9]+.?[0-9]{0,2}/g)[0]
        kb = kb === "0.00" ? "0.01" : kb
        if (Number(kb) >= 100) {
            kb = kb.substr(0, kb.length - 3)
        }
        if (Number(kb) >= 100000) {
            let mb = Number(kb) / 1024
            mb = String(mb).match(/^[0-9]+/g)[0]
            return `${mb} mb`
        }
        return `${kb} kb`;
    }
</script>
</html>